/*

qutexrlib QT-based XML-RPC library
Copyright (C) 2003  P. Oscar Boykin <boykin@pobox.com>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   
*/

#ifndef xrclient
#define xrclient

#include <qurl.h>
#include <qvariant.h>
#include <qdom.h>
#include <qmap.h>
#include <qbuffer.h>
#include "xrmethodcall.h"
#include "xrmethodresponse.h"
#include "xrfaultcodes.h"
#include <Q3HttpResponseHeader>

/**
 * Represents the client which calls the methods on the remote machine.
 * @see http://www.xmlrpc.com/spec
 * @see http://www.ietf.org/internet-drafts/draft-megacz-xmc-01.txt
 */

class XRClient : public QObject {
   Q_OBJECT
	
    public:
	/**
	 * @param server_url the URL to the server for this client
	 */
        XRClient(const QUrl& server_url,
			QObject * parent = 0,
			const char * name = 0);
	~XRClient();
	/**
	 * Allow the server to send us compressed (deflate)
	 * responses.  Useful to turn this off if debugging
	 * with a network sniffing tool
	 */
	void acceptCompressed(bool arg) { _accept_compressed = arg; }
	/**
	 * @param method the method on the server to call
	 * @param params a list of the parameters
	 * @return the identifier for this response
	 */
        int call(const QString& method,
                 const QList<QVariant>& params);
	
	/**
	 * @return the url of the XML-RPC server
	 */
	const QUrl& getUrl() const { return _url; }
	
	void setUrl(const QUrl& server_url);

    signals:
	/**
	 * this signal is emitted when a NON-FAULT
	 * XML-RPC response is recieved.  You must also
	 * watch for the fault signals
	 * @param response_num the response number for this fault
	 * @param response the deserialized response to the methodCall
	 * @see call
	 */
	void methodResponse(int response_num,
			    const QVariant& response);

	/**
	 * @param response_num the response number for this fault
	 * @param fault_num the faultCode.
	 * @param fault_string the faultString
	 * @see http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
	 * @see call
	 */
	void fault(int response_num, int fault_num, const QString& fault_string);
	
    public slots:
	/**
	 * this is slot which is useful for some GUI widgets
	 */
	void setUrl(const QString& u);
	
    protected slots:
	/**
         * connected to Q3Http methods to handle the Http responses.
	 */
        void processHttpResponse(int http_resp, bool error);
        void processHeaders(const Q3HttpResponseHeader &resp);
	    
    protected:
        Q3Http _http_client;
	QUrl _url;
	bool _is_deflated;
	bool _accept_compressed;
	/**
	 * This is the string passed in the User-Agent: header field.
	 */
	static const QString USER_AGENT;
	/**
	 * Stores the buffers for each request.  These buffers
	 * are deleted after the request is handled.
	 */
	QMap<int, QBuffer*> _buffer_map;
};

#endif
